package com.qigao.mall.channel.weichat;

import com.alibaba.fastjson.JSONObject;
import com.qigao.mall.channel.ChannelCore;
import com.qigao.mall.channel.config.ChannelConstant;
import com.qigao.mall.channel.dto.MerEnterReqDto;
import com.qigao.mall.channel.dto.MerEnterRspDto;
import com.qigao.mall.commons.dto.MerChannelDto;
import com.qigao.mall.commons.enums.ChannelActionEnum;
import com.qigao.mall.commons.enums.ChannelCodeEnum;
import com.qigao.mall.commons.enums.ChannelInfoEnum;
import com.qigao.mall.commons.enums.PayProductEnum;
import com.qigao.mall.commons.param.ChannelReqParam;
import com.qigao.mall.commons.param.ChannelRespParam;
import com.qigao.mall.commons.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class WeiChatMerEnter implements ChannelCore {
    @Autowired
    private WeiChatGetCertficates weiChatGetCertficates;
    @Resource
    ChannelConstant channelConstant;

    public static void main(String[]args) throws Exception {
        WeiChatMerEnter weiChatMerSettled=new WeiChatMerEnter();
        weiChatMerSettled.merEnter(null,null);
    }

    public ChannelRespParam merEnter(MerChannelDto merChannelDto, MerEnterReqDto merEnterReqDto){
        String reqParam;
        try {
            reqParam = buildReqParam(merChannelDto,merEnterReqDto);
            log.info("商户进件,请求参数:【{}】",reqParam);
            String responseParam=HttpClientUtil.doPostStrSSL("https://api.mch.weixin.qq.com/applyment/micro/submit",reqParam,"cert/apiclient_cert.p12","1578082901");
            Map<String,String> respMap=WXPayUtil.xmlToMap(responseParam);
            if ("SUCCESS".equals(respMap.get("return_code"))){
                boolean is=WXPayUtil.isSignatureValid(respMap,"3386ead9287e2f9e78B507F7C0D4D281",WXPayUtil.SignType.HMACSHA256);
                if (!is){
                    return ChannelRespParam.error("返回参数验签失败");
                }
            }else {
                return ChannelRespParam.error(respMap.get("return_msg"));
            }
            log.info("商家进件,返回结构:【{}】",responseParam);
            return  buildRespParam(respMap);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("商家进件，处理发生异常:{}",e);
            return ChannelRespParam.error("进件处理失败");
        }
    }

    private ChannelRespParam buildRespParam(Map<String, String> respMap) {
        MerEnterRspDto merEnterRspDto=new MerEnterRspDto();
        //todo 参数封装

        String retStr= JSONObject.toJSONString(merEnterRspDto);
        ChannelRespParam channelRespParam=new ChannelRespParam();
        channelRespParam.setRespCode(ChannelCodeEnum.SUCCESS.getCode());
        channelRespParam.setRespMsg(ChannelCodeEnum.SUCCESS.getName());
        channelRespParam.setRespContent(retStr);
        return channelRespParam;
    }

    private String buildReqParam(MerChannelDto merChannelDto,MerEnterReqDto merEnterReqDto) throws Exception {
        Map commonReqParam=new ConcurrentHashMap<>();
        commonReqParam.put("version","3.0");//接口版本号
        //获取平台序列号
        //commonReqParam.put("cert_sn","4C7CDE1A8E7C93347E6C6F1DFEA95304D57AD9A3");//平台证书序列号
        commonReqParam.put("cert_sn",channelConstant.getWeichatPlatCertSn());
        commonReqParam.put("mch_id",merEnterReqDto.getPlatMerNo());//商户号
        commonReqParam.put("nonce_str", WXPayUtil.generateNonceStr());
        commonReqParam.put("sign_type", "HMAC-SHA256");
        commonReqParam.put("business_code", merEnterReqDto.getBusinessCode());//业务申请编号
        commonReqParam.put("id_card_copy", "Z5Y4oOguBa-DUF0UYLzlOZLHeARpAQ7SoiwSmtK661-RIzUHV9tcmy7A0ktjExabBQsyp_APQ9uWEuGBkHrjmtWXQwaDRj2lNR2VVc2k5XM");//身份证人像面照片
        commonReqParam.put("id_card_national", "Z5Y4oOguBa-DUF0UYLzlOZLHeARpAQ7SoiwSmtK661-RIzUHV9tcmy7A0ktjExabBQsyp_APQ9uWEuGBkHrjmtWXQwaDRj2lNR2VVc2k5XM");//身份证国徽面照片
        commonReqParam.put("id_card_name", WXRSAEncrypt.rsaEncrypt((merEnterReqDto.getIdCardName())));//身份证姓名
        commonReqParam.put("id_card_number", WXRSAEncrypt.rsaEncrypt(merEnterReqDto.getIdCardNumber()));//身份证号码
        commonReqParam.put("id_card_valid_time", merEnterReqDto.getIdCardValidTime());//身份证有效期限
        commonReqParam.put("account_name", WXRSAEncrypt.rsaEncrypt(merEnterReqDto.getAccountName()));//开户名称
        commonReqParam.put("account_bank", merEnterReqDto.getAccountBank());//开户银行
        commonReqParam.put("bank_address_code", merEnterReqDto.getBankAddressCode());//开户银行省市编码

        commonReqParam.put("account_number", WXRSAEncrypt.rsaEncrypt(merEnterReqDto.getAccountNumber()));//银行账号
        commonReqParam.put("store_name", merEnterReqDto.getStoreName());//门店名称
        commonReqParam.put("store_address_code", merEnterReqDto.getStoreStreet());//门店省市编码
        commonReqParam.put("store_street", merEnterReqDto.getStoreStreet());//门店街道名称
        commonReqParam.put("store_entrance_pic", "Z5Y4oOguBa-DUF0UYLzlOZLHeARpAQ7SoiwSmtK661-RIzUHV9tcmy7A0ktjExabBQsyp_APQ9uWEuGBkHrjmtWXQwaDRj2lNR2VVc2k5XM");//门店门口照片
        commonReqParam.put("indoor_pic", "Z5Y4oOguBa-DUF0UYLzlOZLHeARpAQ7SoiwSmtK661-RIzUHV9tcmy7A0ktjExabBQsyp_APQ9uWEuGBkHrjmtWXQwaDRj2lNR2VVc2k5XM");//店内环境照片
        commonReqParam.put("merchant_shortname", merEnterReqDto.getMerchantShortname());//商户简称
        commonReqParam.put("service_phone", merEnterReqDto.getServicePhone());//客服电话
        commonReqParam.put("product_desc", merEnterReqDto.getProductDesc());//售卖商品/提供服务描述
        commonReqParam.put("rate", merEnterReqDto.getRate());//费率
        commonReqParam.put("contact", WXRSAEncrypt.rsaEncrypt(merEnterReqDto.getContact()));//超级管理员姓名
        commonReqParam.put("contact_phone", WXRSAEncrypt.rsaEncrypt(merEnterReqDto.getContactPhone()));//手机号码
        String signValue= WXPayUtil.generateSignature(commonReqParam,merChannelDto.getMd5Key(),WXPayUtil.SignType.HMACSHA256);
        commonReqParam.put("sign",signValue);
        return PayUtil.mapToXml(commonReqParam);
    }

    /**
     * 上传身份证图片
     * @return
     */
    private ChannelRespParam uploadMedia() throws Exception {
        File file=new File("D:\\tupian\\123.jpg");
        InputStream inputStream=null;
        try {
            inputStream=new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Map commonReqParam=new ConcurrentHashMap<>();
        commonReqParam.put("mch_id","1578082901");//商户号
        commonReqParam.put("media_hash",WXPayUtil.md5HashCode(inputStream));// 媒体文件内容hash值
        commonReqParam.put("sign_type","HMAC-SHA256");//签名方式
        try {
            String signValue= WXPayUtil.generateSignature(commonReqParam,"3386ead9287e2f9e78B507F7C0D4D281",WXPayUtil.SignType.HMACSHA256);
            commonReqParam.put("sign",signValue);
            String responseParam=HttpClientUtil.doPostMutPart("https://api.mch.weixin.qq.com/secapi/mch/uploadmedia",commonReqParam,inputStream,"cert/apiclient_cert.p12","1578082901");
            Map<String,String> respMap=WXPayUtil.xmlToMap(responseParam);
            Boolean isSign=WXPayUtil.isSignatureValid(respMap,"3386ead9287e2f9e78B507F7C0D4D281",WXPayUtil.SignType.HMACSHA256);
            if (!isSign)return ChannelRespParam.error("签名效验不通过");
            if ("SUCCESS".equals(respMap.get("result_code"))){
                return ChannelRespParam.success(respMap.get("media_id"),"成功");
            }else {
                return ChannelRespParam.error("图片上传失败");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public boolean isSupport(PayProductEnum payProductEnum, ChannelActionEnum channelActionEnum, ChannelInfoEnum channelInfoEnum) {
        return ChannelActionEnum.MER_ENTER.equals(channelActionEnum) &&
                PayProductEnum.WEICHAT_SMALL_ENTER.equals(payProductEnum)&&
                ChannelInfoEnum.WEICHAT.equals(channelInfoEnum)
                ;
    }

    @Override
    public ChannelRespParam channelProcess(MerChannelDto merChannelDto, ChannelReqParam channelReqParam) {
        MerEnterReqDto merEnterReqDto=JSONObject.parseObject(channelReqParam.getReqContent(),MerEnterReqDto.class);
        return merEnter(merChannelDto,merEnterReqDto);
    }
}
